package bcontractor.propositional;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.junit.Test;

/**
 * Tests for PropositionalSentence
 * 
 * @author lundberg
 * 
 */
public class PropositionalSentenceShould {

    @Test
    public void storeLiteralsSorted() {
        PropositionalSentence s = new PropositionalSentence(new int[][] { { 3, 1, 2 } });
        this.assertEquals(new int[][] { { 1, 2, 3 } }, s.getClauses());
    }

    @Test
    public void storeLiteralsSortedRespectingSign() {
        PropositionalSentence s = new PropositionalSentence(new int[][] { { 3, 1, -2 } });
        this.assertEquals(new int[][] { { -2, 1, 3 } }, s.getClauses());
    }

    @Test
    public void storeClausesSortedBySize() {
        PropositionalSentence s = new PropositionalSentence(new int[][] { { 1, 2, 3 }, { 1 }, { 1, 2 }, { 3, 1, 2 } });
        this.assertEquals(new int[][] { { 1 }, { 1, 2 }, { 1, 2, 3 }, { 1, 2, 3 } }, s.getClauses());
    }

    @Test
    public void storeClausesOrderedByLiteralAfterClauseSize() {
        PropositionalSentence s = new PropositionalSentence(new int[][] { { 1, 3 }, { 1, 2 }, { -1 }, { 1 } });
        this.assertEquals(new int[][] { { -1 }, { 1 }, { 1, 2 }, { 1, 3 } }, s.getClauses());
    }

    @Test
    public void shouldImplementEqualsHashCodeToString() {
        PropositionalSentence sentence = new PropositionalSentence(new int[][] { { 1, 2 }, { 2 } });
        assertThat(sentence.hashCode(), not(System.identityHashCode(sentence.hashCode())));
        assertThat(sentence.equals(sentence), is(true));
        assertThat(sentence.equals(new Object()), is(false));

        assertThat(sentence.equals(new PropositionalSentence(new int[][] { { 1, 2 }, { -2 } })), is(false));

        assertThat(sentence.hashCode(), not(new PropositionalSentence(new int[][] { { 1 }, { -2 } }).hashCode()));

        assertThat(sentence.toString(), not(containsString("@")));

        assertThat(sentence.toString(), not(new PropositionalSentence(new int[][] { { 1 }, { -2 } }).toString()));
    }

    private void assertEquals(int[][] expected, int[][] actual) {
        assertThat(new EqualsBuilder().append(expected, actual).isEquals(), is(true));
    }
}
